package com.muyu.kafka.sche;

import com.alibaba.fastjson.JSONObject;
import com.muyu.kafka.domain.AllData;
import com.muyu.kafka.domain.Data1;
import com.muyu.kafka.domain.Data2;
import com.muyu.kafka.domain.Data3;
import com.muyu.kafka.service.KafkaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.*;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @ClassName ScheTest
 * @Description 描述
 * @Author LiuZeZhang
 * @Date 2024/04/11 19:53
 */
@Component
public class Sche {

    @Autowired
    private KafkaService kafkaService;

    @Value("${file.save.path}")
    private String fileSavePath;

    @Value("${file.save.xmlPath}")
    private String fileSaveXmlPath;

    @Value("${file.format.xml}")
    private String xmlFormat;

    @Value("${file.format.jpg}")
    private String jpgFormat;

    @Value("${file.format.bcp}")
    private String bcpFormat;

    @Value("${file.name.bcpName}")
    private String bcpName;

    @Value("${file.format.zip}")
    private String zipFormat;

    @Value("${file.compress.directory.bcp}")
    private String bcpDirectory;

    @Value("${file.compress.directory.xml}")
    private String xmlDirectory;

    @Value("${file.compress.directory.photo1}")
    private String photo1Directory;

    @Value("${file.compress.directory.photo2}")
    private String photo2Directory;

    @Value("${redis.name.key}")
    private String key;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Scheduled(cron = "0/30 * * * * ?")
    public void test()  {
        if (!redisTemplate.hasKey(key)){
            List<Data1> data1All = kafkaService.findData1All();
            for (Data1 data1 : data1All) {
                Data2 data2 = findData2(data1.getId());
                Data3 data3 = findData3(data1.getId());
                if (data2==null ||data3==null){
                    continue;
                }
                // 图片保存
                String photoName1 = savePhoto(data2.getPhoto1(),  System.currentTimeMillis() + jpgFormat);
                String photoName2 = savePhoto(data2.getPhoto2(),  System.currentTimeMillis() + jpgFormat);

                StringBuffer stringBuffer = new StringBuffer();
                stringBuffer.append(data1.getId()).append("\t").append(data1.getXm())
                        .append("\t").append(data1.getCard())
                        .append("\t").append(data1.getAge())
                        .append("\t").append(data1.getTime())
                        .append("\t").append(photoName1)
                        .append("\t").append(photoName2)
                        .append("\t").append(data3.getPlate()).append("\t");
                // 生成bcp文件
                String bcpFileName = generateBcpFile(stringBuffer);
                // 生成xml文件
                String xmlFileName = generateXmlFile(bcpFileName);
                // 压缩文件为zip
                compressFiles(bcpFileName, xmlFileName, photoName1, photoName2);

                // 删除文件
                deleteFiles(fileSavePath+bcpFileName, xmlFileName,photoName1,photoName2);

                //删除数据库
                deleteData(data1.getId());
            }
        }else {
            List<String> list = redisTemplate.opsForList().range(key, 0, -1);
            Date latestTime = null;

            for (String string : list) {
                AllData dataAll = JSONObject.parseObject(string, AllData.class);
                Date currentTime = dataAll.getTime();
                // 如果latestTime为空，或者currentTime比latestTime更新，则更新latestDataAll和latestTime
                if (latestTime == null || currentTime.after(latestTime)) {
                    latestTime = currentTime;
                }
            }

            redisTemplate.opsForValue().set("dataLstTime",latestTime.toString());
            List<Data1> data1List = kafkaService.findData1ByTime(latestTime);
            for (Data1 data1 : data1List) {

                Data2 data2 = findData2(data1.getId());
                Data3 data3 = findData3(data1.getId());

                if (data2==null ||data3==null){
                    continue;
                }
                // 图片保存
                String photoName1 = savePhoto(data2.getPhoto1(),  System.currentTimeMillis() + jpgFormat);
                String photoName2 = savePhoto(data2.getPhoto2(),  System.currentTimeMillis() + jpgFormat);

                StringBuffer stringBuffer = new StringBuffer();
                stringBuffer.append(data1.getId())
                        .append("\t").append(data1.getXm())
                        .append("\t").append(data1.getCard())
                        .append("\t").append(data1.getAge())
                        .append("\t").append(data1.getTime())
                        .append("\t").append(photoName1)
                        .append("\t").append(photoName2)
                        .append("\t").append(data3.getPlate()).append("\t");
                // 生成bcp文件
                String bcpFileName = generateBcpFile(stringBuffer);
                // 生成xml文件
                String xmlFileName = generateXmlFile(bcpFileName);
                // 压缩文件为zip
                compressFiles(bcpFileName, xmlFileName, photoName1, photoName2);

                // 删除文件
                deleteFiles(fileSavePath+bcpFileName, xmlFileName,photoName1,photoName2);
            }
        }
    }
    private Data2 findData2(BigInteger id) {
        CompletableFuture<Data2> data2Future = CompletableFuture.supplyAsync(() -> kafkaService.finddata2(id));
        return data2Future.join();
    };
    private Data3 findData3(BigInteger id){
        CompletableFuture<Data3> data3Future = CompletableFuture.supplyAsync(() -> kafkaService.finddata3(id));
        return data3Future.join();
    };

    // 图片保存方法
    private String savePhoto(String photoBase64, String photoName) {
        byte[] decodedBytes = Base64.getDecoder().decode(photoBase64);
        // 存储路径
        String filePath = fileSavePath + photoName;
        try (FileOutputStream fos = new FileOutputStream(filePath)) {
            fos.write(decodedBytes);
        } catch (IOException e) {
            e.printStackTrace();
            // 可以添加异常处理逻辑，比如记录日志
        }
        return filePath;
    }

    // 生成bcp文件
    private String generateBcpFile(StringBuffer stringBuffer) {
        // 生成唯一的bcp文件名称
        String bcpFileName = System.currentTimeMillis() + bcpFormat;
        // 存储路径
        String filePath = fileSavePath + bcpFileName;
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            // 拼接字符串并写入到文件中
            writer.write(stringBuffer.toString());
        } catch (IOException e) {
            e.printStackTrace();
            // 可以添加异常处理逻辑，比如记录日志
        }
        return bcpFileName;
    }

    // 生成xml文件
    // 生成xml文件
    private String generateXmlFile(String fileName) {
        // 模板文件路径
        String templateFilePath = fileSaveXmlPath;
        // 输出文件路径
        String outputFilePath = fileSavePath + fileName + xmlFormat;
        try {
            String xmlTemplate = new String(Files.readAllBytes(Paths.get(templateFilePath)));
            // 替换文件名称
            xmlTemplate = xmlTemplate.replace(bcpName, fileName);
            // 写入新的xml内容到文件中
            Files.write(Paths.get(outputFilePath), xmlTemplate.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
            // 可以添加异常处理逻辑，比如记录日志
        }
        return outputFilePath;
    }

    // 压缩文件为zip
    public void compressFiles(String bcpFileName, String xmlFileName, String photoName1, String photoName2) {
        try {

            // 创建一个ZipOutputStream，它将写入一个名为"compressed.zip"的文件
            FileOutputStream fos = new FileOutputStream(fileSavePath + File.separator + zipFormat);
            ZipOutputStream zos = new ZipOutputStream(fos);

            // 压缩文件的方法
            addFileToZip(fileSavePath+bcpFileName, zos, bcpDirectory);
            addFileToZip(xmlFileName, zos, xmlDirectory);
            addFileToZip(photoName1, zos, photo1Directory);
            addFileToZip(photoName2, zos, photo2Directory);

            // 关闭ZipOutputStream
            zos.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void addFileToZip(String filePath, ZipOutputStream zos, String entryName) throws IOException {
        // 打开文件
        FileInputStream fis = new FileInputStream(filePath);
        ZipEntry zipEntry = new ZipEntry(entryName + new File(filePath).getName());
        zos.putNextEntry(zipEntry);

        // 复制文件内容到ZIP输出流
        byte[] bytes = new byte[1024];
        int length;
        while ((length = fis.read(bytes)) >= 0) {
            zos.write(bytes, 0, length);
        }
        // 关闭文件输入流
        fis.close();
    }

    // 删除文件
    private void deleteFiles(String... fileNames) {
        for (String fileName : fileNames) {
            String filePath = fileName;
            try {
                Files.deleteIfExists(Paths.get(filePath));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 删除数据库中的数据
    private void deleteData(BigInteger id) {
        kafkaService.delete1ById(id);
        kafkaService.delete2ById(id);
        kafkaService.delete3ById(id);
    }


}
